﻿using System.Text;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.MessagePatterns;
using smp.RabbitMq.Strategies;

namespace smp.RabbitMq
{
    internal class ResponderServer : SimpleRpcServer
    {
        private readonly ResponderHandlers _handlers;
        private readonly IResponderStrategy _strategy;
        private readonly RabbitMqBusBase _bus;
        private readonly ILog _log;

        public ResponderServer(Subscription subscription, ResponderHandlers handlers, IResponderStrategy strategy, RabbitMqBusBase busBase, ILog log)
            : base(subscription)
        {
            _handlers = handlers;
            _strategy = strategy;
            _bus = busBase;
            _log = log;
        }

        public override byte[] HandleSimpleCall(bool isRedelivered, IBasicProperties requestProperties, byte[] body, out IBasicProperties replyProperties)
        {
            replyProperties = null;
            var envelope = _bus.GetEnvelopeFromPacket(body);
            if(envelope == null)
            {
                _log.Warning("Null or empty message packet recieved");
                return null;
            }


            var messageEntity = _bus.DeserializeMessage(envelope.MessageType, envelope.Message);
            if (messageEntity == null)
            {
                _log.Warning("Null or empty message in envelope packet recieved.");
                return null;
            }

            _log.Info("Subscriber recieved message [{0}]", envelope.Message);
            var handler = _handlers.GetHandler(envelope.MessageType);
            if(handler == null)
            {
                _log.Debug("No responder detect for message type {0}", envelope.MessageType);
                return null;
            }

            object result = _strategy.HandleResponse(handler, envelope);

            if (result == null)
                return null;

            var responseEnvelope = _bus.SerializeMessage(result.GetType(), result);
            var serialisedResponse = JsonConvert.SerializeObject(responseEnvelope);
            _bus.Log.Debug("Sending response packet : " + serialisedResponse);
            return Encoding.UTF8.GetBytes(serialisedResponse);
        }
    }
}
